package com.benew.ntt.ydeval

import com.benew.ntt.evaluate.constant.EvalError
import com.benew.ntt.evaluate.sdk.EvalSDKHandler
import com.benew.ntt.ydeval.listener.RecordStreamListener
import com.ntt.core.nlogger.NLogger
import org.java_websocket.client.WebSocketClient
import org.java_websocket.handshake.ServerHandshake
import org.json.JSONObject
import java.net.URI
import java.text.SimpleDateFormat
import java.util.*

class SocketClient(serverUri: URI?, private var content: String) : WebSocketClient(serverUri) {
    companion object {
        private val TAG = SocketClient::class.java.simpleName
    }

    init {
        connectionLostTimeout = 3000
    }

    var mSDKHandler: EvalSDKHandler? = null

    //录音监听
    private val mRecordStreamListener = object : RecordStreamListener {
        override fun recordOfByte(data: ByteArray, begin: Int, end: Int, decibel: Double) {
            try {
                if (isOpen && !isClosing) {
                    try {
                        send(data)
                        mSDKHandler?.recordOfByte(data, begin, end, decibel)
                    } catch (e: Exception) {
                        NLogger.e(TAG, "发送数据！！ 异常:" + e.message)
                    }

                }
            } catch (e: Exception) {
                NLogger.e(TAG, "发送数据异常=${e.message}")
            }
        }

        override fun recordPath(path: String) {
            NLogger.d(TAG, "结束录音路径=$path")
            mSDKHandler?.sendRecordFile(path)
        }

        override fun onEndRecord() {
            NLogger.d(TAG, "结束录音！！！")
            endEval()
            mSDKHandler?.sendRecordEnd()
        }

        override fun startRecord() {
            super.startRecord()
            NLogger.d(TAG, "开始录音！！！")
            mSDKHandler?.sendStartRecord()

        }
    }

    override fun onOpen(data: ServerHandshake) {
        NLogger.d(TAG, "onOpen ==> $data")
    }

    override fun onClose(code: Int, reason: String, remote: Boolean) {
        mSDKHandler?.sendEvalClose()
        CmAudioRecorder.getInstance().cancels()
        NLogger.d(TAG, "onClose code ==> $code", "reason ==> $reason", "remote ==> $remote")
    }

    override fun onError(ex: Exception) {
        mSDKHandler?.sendError(null, EvalError.ERROR_5)
        NLogger.e(TAG, "onError ==> $ex")
    }

    override fun onMessage(message: String?) {
        NLogger.d(TAG, "onMessage ==> $message")
        message?.let {
            mSDKHandler?.sendTimeOutCountDown(7000)
            try {
                val messageObj = JSONObject(message)
                when (messageObj.optString("action")) {
                    "started" -> {
                        content = content.replace("\"", " ")
                        val data = "{\"text\": \"$content\"}"
                        if (isOpen && !isClosing) {
                            NLogger.e("onMessage 发送数据 ：$data")
                            try {
                                send(data)
                            } catch (e: Exception) {
                                NLogger.e(TAG, "started发送数据！！ 异常:" + e.message)
                            }
                        }
                        startRecord()
                    }
                    "capt" -> {
                        val result = messageObj.optJSONObject("result")
                        val intonation = result?.optString("intonation")
                        intonation?.let {
                            val isFinal = result.optBoolean("isFinal")
                            if (isFinal) {
                                mSDKHandler?.sendResult(message)
                            } else {
                                mSDKHandler?.sendEvalProgress(message)
                            }
                        }
                    }
                    "error" -> {
                        CmAudioRecorder.getInstance().stopRecord()
                        mSDKHandler?.sendError(null, EvalError.ERROR_5)
                    }
                    "close" -> {
                        CmAudioRecorder.getInstance().stopRecord()
                        mSDKHandler?.sendEvalClose()
                        closeSocket()
                    }
                    else -> {

                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                NLogger.e(TAG, "评测异常：${e.message}")
                mSDKHandler?.sendError(null, EvalError.ERROR_5)
            }
        }
    }

    /**
     * 开始录音
     */
    private fun startRecord() {
        NLogger.d(TAG, "打开录音！！！")
        // 初始化录音
        val fileName = SimpleDateFormat("yyyyMMddhhmmss").format(Date())
        CmAudioRecorder.getInstance().createDefaultAudio(fileName)
        CmAudioRecorder.getInstance().startRecord(mRecordStreamListener)
    }

    /**
     * 停止录音
     */
    fun stopRecord() {
        CmAudioRecorder.getInstance().stopRecord()
        endEval()
    }

    /**
     * 结束评测
     */
    fun endEval() {
        if (isOpen && !isClosing) {
            NLogger.d(TAG, "发送结束评测！！！{\"end\":\"true\"}")
            try {
                send("{\"end\":\"true\"}".toByteArray())
            } catch (e: Exception) {
                NLogger.e(TAG, "发送结束评测！！ 异常:" + e.message)
            }
        }
    }

    /**
     * 释放资源
     */
    fun releaseRes() {
        try {
            mSDKHandler = null
            CmAudioRecorder.getInstance().cancels()
            CmAudioRecorder.getInstance().setListener(null)
            CmAudioRecorder.getInstance().release()
        } catch (e: Exception) {
            NLogger.e(TAG, "录音关闭异常！！！", e.message)
        }
        closeSocket()
    }

    /**
     * 关闭socket
     */
    fun closeSocket() {
        try {
            if (isOpen && !isClosing) {
                close()
            }
        } catch (e: Exception) {
            NLogger.e(TAG, "socket关闭异常！！！", e.message)
        }
    }

    fun start() {
        NLogger.d(TAG, "start")
        connect()
    }
}